home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / jade / src / windows.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  20KB  |  770 lines

  1. /* windows.c -- System-independant window handling
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #include <stdarg.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. _PR void messagen(u_char *, int);
  28. _PR void message(u_char *);
  29. _PR void messagef(u_char *, ...);
  30. _PR void no_message(VW *);
  31. _PR void std_message(VW *);
  32. _PR void reset_message(VW *);
  33. _PR void refresh_message(VW *);
  34. _PR void windows_init(void);
  35. _PR void windows_kill(void);
  36. _PR void window_sweep(void);
  37. _PR void window_prin(VALUE, VALUE);
  38.  
  39. VALUE sym_make_window_hook, sym_destroy_window_hook;
  40.  
  41. /* This can contain `dead' windows, ie vw_Window==NULL, they have been
  42.    close'd but must hang around until we're sure all refs are dead.  */
  43. _PR   VW     *view_chain;
  44. /* curr_vw is the active window */
  45. _PR   VW     *curr_vw;
  46. _PR   int      window_count;
  47. _PR   bool  log_messages;
  48.  
  49. VW   *view_chain;
  50. VW   *curr_vw;
  51. int   window_count;
  52. bool  log_messages;
  53.  
  54. _PR short def_dims[4];
  55. short def_dims[4] = { 0, 0, 80, 24 };
  56.  
  57. static void
  58. copy_prefs(VW *dest, VW *src)
  59. {
  60.     if(src)
  61.     {
  62.     dest->vw_MaxScroll = src->vw_MaxScroll;
  63.     dest->vw_XStepRatio = src->vw_XStepRatio;
  64.     dest->vw_YStepRatio = src->vw_YStepRatio;
  65.     dest->vw_Flags = src->vw_Flags;
  66.     dest->vw_FontName = src->vw_FontName;
  67. #ifdef HAVE_AMIGA
  68.     dest->vw_WindowSys.ws_FontSize = src->vw_WindowSys.ws_FontSize;
  69.     dest->vw_WindowSys.ws_ScreenName = src->vw_WindowSys.ws_ScreenName;
  70. #endif
  71.     }
  72.     else
  73.     {
  74.     dest->vw_MaxScroll = 20;
  75.     dest->vw_XStepRatio = 4;
  76. #ifdef HAVE_AMIGA
  77.     dest->vw_YStepRatio = 0;
  78. #else
  79.     dest->vw_YStepRatio = 4;
  80. #endif
  81.     dest->vw_Flags = 0;
  82.     dest->vw_FontName = def_font_str;
  83. #ifdef HAVE_AMIGA
  84.     dest->vw_WindowSys.ws_FontSize = ami_def_font_size;
  85.     dest->vw_WindowSys.ws_ScreenName = ami_def_pub_screen;
  86. #endif
  87.     }
  88. }
  89.  
  90. _PR VALUE cmd_make_window(VALUE xv, VALUE yv, VALUE wv, VALUE hv);
  91. DEFUN("make-window", cmd_make_window, subr_make_window, (VALUE xv, VALUE yv, VALUE wv, VALUE hv), V_Subr4, DOC_make_window) /*
  92. ::doc:make_window::
  93. make-window [X] [Y] [WIDTH] [HEIGHT]
  94.  
  95. Return a new window, it will be displaying the same buffer as the currently
  96. active window.
  97. ::end:: */
  98. {
  99.     VW *vw;
  100.     TX *tx = curr_vw ? curr_vw->vw_Tx : NULL;
  101.     if(NUMBERP(xv))
  102.     def_dims[0] = VNUM(xv);
  103.     if(NUMBERP(yv))
  104.     def_dims[1] = VNUM(yv);
  105.     if(NUMBERP(wv))
  106.     def_dims[2] = VNUM(wv);
  107.     if(NUMBERP(hv))
  108.     def_dims[3] = VNUM(hv);
  109.     vw = mycalloc(sizeof(VW));
  110.     if(vw)
  111.     {
  112.     vw->vw_Type = V_Window;
  113.     vw->vw_Next = view_chain;
  114.     view_chain = vw;
  115.     copy_prefs(vw, curr_vw);
  116.     if(sys_set_font(vw))
  117.     {
  118.         vw->vw_Window = sys_new_window(curr_vw, vw, TRUE);
  119.         if(vw->vw_Window)
  120.         {
  121.         window_count++;
  122.         sys_new_vw(vw);
  123.         vw->vw_BlockStatus = -1;
  124.         vw->vw_BufferList = sym_nil;
  125.         sys_update_dimensions(vw);
  126.         if(tx)
  127.         {
  128.             vw->vw_Tx = tx;
  129.             vw->vw_CursorPos = tx->tx_SavedCPos;
  130.             vw->vw_StartLine = tx->tx_SavedWPos.pos_Line;
  131.             vw->vw_StartCol = tx->tx_SavedWPos.pos_Col;
  132.             std_message(vw);
  133.             cmd_eval_hook2(sym_make_window_hook, VAL(vw));
  134. #ifndef NOSCRLBAR
  135.             sys_update_scroller(vw);
  136. #endif
  137.         }
  138.         vw->vw_Flags |= VWFF_FORCE_REFRESH;
  139.         return(VAL(vw));
  140.         }
  141.         sys_unset_font(vw);
  142.     }
  143.     myfree(vw);
  144.     }
  145.     return(NULL);
  146. }
  147.  
  148. _PR VALUE cmd_destroy_window(VALUE win);
  149. DEFUN("destroy-window", cmd_destroy_window, subr_destroy_window, (VALUE win), V_Subr1, DOC_destroy_window) /*
  150. ::doc:destroy_window::
  151. destroy-window [WINDOW]
  152.  
  153. Close WINDOW (or the current window), if this was the last one all files in
  154. memory are flushed and jade will exit.
  155. ::end:: */
  156. {
  157.     VW *vw = WINDOWP(win) ? VWIN(win) : curr_vw;
  158.     cmd_eval_hook2(sym_destroy_window_hook, VAL(vw));
  159.     no_message(vw);
  160.     /* This function is to take care of OS-independant stuff:
  161.        releasing GCs etc...  */
  162.     sys_kill_vw(vw);
  163.     sys_kill_window(vw);
  164.     sys_unset_font(vw);
  165.     window_count--;
  166.     /* This flags that this window is dead.  */
  167.     vw->vw_Window = WINDOW_NIL;
  168.     vw->vw_Tx = NULL;
  169.     vw->vw_BufferList = sym_nil;
  170.     if(curr_vw == vw)
  171.     {
  172.     while((vw = vw->vw_Next))
  173.     {
  174.         if(vw->vw_Window)
  175.         {
  176.         curr_vw = vw;
  177.         return(VAL(vw));
  178.         }
  179.     }
  180.     vw = view_chain;
  181.     while(vw && (vw != curr_vw))
  182.     {
  183.         if(vw->vw_Window)
  184.         {
  185.         curr_vw = vw;
  186.         return(VAL(vw));
  187.         }
  188.         vw = vw->vw_Next;
  189.     }
  190.     /* No living windows left :-( we'll die soon :-(  */
  191.     curr_vw = NULL;
  192.     throw_value = cmd_cons(sym_quit, make_number(0)); /* experimental. */
  193.     return(NULL);
  194.     }
  195.     return(VAL(curr_vw));
  196. }
  197.  
  198. _PR VALUE cmd_sleep_window(VALUE vw);
  199. DEFUN_INT("sleep-window", cmd_sleep_window, subr_sleep_window, (VALUE vw), V_Subr1, DOC_sleep_window, "") /*
  200. ::doc:sleep_window::
  201. sleep-window [WINDOW]
  202.  
  203. Iconifies the current window.
  204. ::end:: */
  205. {
  206.     if(!WINDOWP(vw))
  207.     vw = VAL(curr_vw);
  208.     if(((VWIN(vw)->vw_Flags & VWFF_SLEEPING) == 0)
  209.        && sys_sleep_vw(VWIN(vw)))
  210.     return(vw);
  211.     return(sym_nil);
  212. }
  213.  
  214. _PR VALUE cmd_unsleep_window(VALUE vw);
  215. DEFUN_INT("unsleep-window", cmd_unsleep_window, subr_unsleep_window, (VALUE vw), V_Subr1, DOC_unsleep_window, "") /*
  216. ::doc:unsleep_window::
  217. unsleep-window [WINDOW]
  218.  
  219. Uniconifies the current window.
  220. ::end:: */
  221. {
  222.     if(!WINDOWP(vw))
  223.     vw = VAL(curr_vw);
  224.     if((VWIN(vw)->vw_Flags & VWFF_SLEEPING) && sys_unsleep_vw(VWIN(vw)))
  225.     return(vw);
  226.     return(sym_nil);
  227. }
  228.  
  229. _PR VALUE cmd_next_window(VALUE vw, VALUE activ);
  230. DEFUN_INT("next-window", cmd_next_window, subr_next_window, (VALUE vw, VALUE activ), V_Subr2, DOC_next_window, "!\np") /*
  231. ::doc:next_window::
  232. next-window [WINDOW] [ACTIVATE]
  233.  
  234. Cycles through the open windows forwards.
  235. ::end:: */
  236. {
  237.     if(!WINDOWP(vw))
  238.     vw = VAL(curr_vw->vw_Next);
  239.     while(VWIN(vw) != curr_vw)
  240.     {
  241.     if(!vw)
  242.         vw = VAL(view_chain);
  243.     if(VWIN(vw)->vw_Window)
  244.     {
  245.         if(!NILP(activ))
  246.         {
  247.         curr_vw = VWIN(vw);
  248.         sys_activate_win(VWIN(vw));
  249.         }
  250.         return(vw);
  251.     }
  252.     vw = VAL(VWIN(vw)->vw_Next);
  253.     }
  254.     return(VAL(curr_vw));
  255. }
  256.  
  257. void
  258. messagen(u_char *title, int length)
  259. {
  260.     VW *vw = curr_vw;
  261.     if(log_messages)
  262.     {
  263.     fwrite(title, 1, length, stderr);
  264.     fputc('\n', stderr);
  265.     }
  266.     if((vw->vw_Flags & VWFF_SLEEPING) == 0)
  267.     {
  268.     str_free(vw->vw_Message);
  269.     vw->vw_Message = str_dupn(title, length);
  270.     vw->vw_MessageLen = length;
  271.     vw->vw_Flags |= VWFF_REFRESH_STATUS | VWFF_MESSAGE;
  272.     }
  273. }
  274.  
  275. void
  276. message(u_char *msg)
  277. {
  278.     messagen(msg, strlen(msg));
  279. }
  280.  
  281. void
  282. messagef(u_char *fmt, ...)
  283. {
  284.     VW *vw = curr_vw;
  285.     va_list args;
  286.     if((vw->vw_Flags & VWFF_SLEEPING) == 0)
  287.     {
  288.     u_char fmtbuff[256];
  289.     u_long len;
  290.     va_start(args, fmt);
  291.     vsprintf(fmtbuff, fmt, args);
  292.     va_end(args);
  293.     if(log_messages)
  294.        fprintf(stderr, "%s\n", fmtbuff);
  295.     str_free(vw->vw_Message);
  296.     len = strlen(fmtbuff);
  297.     vw->vw_Message = str_dupn(fmtbuff, len);
  298.     vw->vw_MessageLen = len;
  299.     vw->vw_Flags |= VWFF_REFRESH_STATUS | VWFF_MESSAGE;
  300.     }
  301. }
  302.  
  303. void
  304. no_message(VW *vw)
  305. {
  306.     if(((vw->vw_Flags & VWFF_SLEEPING) == 0) && vw->vw_Message)
  307.     {
  308.     str_free(vw->vw_Message);
  309.     vw->vw_Message = NULL;
  310.     vw->vw_MessageLen = 0;
  311.     vw->vw_Flags &= ~VWFF_MESSAGE;
  312.     vw->vw_Flags |= VWFF_REFRESH_STATUS;
  313.     }
  314. }
  315.  
  316. void
  317. std_message(VW *vw)
  318. {
  319.     if(((vw->vw_Flags & VWFF_MESSAGE) == 0)
  320.        && ((vw->vw_Flags & VWFF_SLEEPING) == 0))
  321.     {
  322.     TX *tx = vw->vw_Tx;
  323.     u_char *blk;
  324.     u_char fmtbuff[100];
  325.     u_long len;
  326.     if(vw->vw_BlockStatus >= 0)
  327.     {
  328.         if(vw->vw_BlockStatus == 0)
  329.         blk = "B";
  330.         else
  331.         blk = "b";
  332.     }
  333.     else
  334.         blk = "";
  335.     str_free(vw->vw_Message);
  336.     calc_cursor_offset(vw);
  337.     sprintf(fmtbuff, "%s%s %c%s%s%c (%ld,%ld) %ld line(s) %s",
  338.         VSTR(tx->tx_BufferName),
  339.         ((tx->tx_Changes != tx->tx_ProperSaveChanges) && (!(tx->tx_Flags & TXFF_SPECIAL))) ? "+" : (tx->tx_Flags & TXFF_RDONLY ? "-" : ""),
  340.         (recurse_depth ? '[' : '('),
  341.         (tx->tx_ModeName ? (char *)VSTR(tx->tx_ModeName) : "generic"),
  342.         VSTR(tx->tx_MinorModeNameString),
  343.         (recurse_depth ? ']' : ')'),
  344.         vw->vw_LastCursorOffset + 1,
  345.         vw->vw_CursorPos.pos_Line + 1,
  346.         tx->tx_NumLines,
  347.         blk);
  348.     len = strlen(fmtbuff);
  349.     vw->vw_Message = str_dupn(fmtbuff, len);
  350.     vw->vw_MessageLen = len;
  351.     vw->vw_Flags |= VWFF_REFRESH_STATUS;
  352.     }
  353. }
  354.  
  355. void
  356. reset_message(VW *vw)
  357. {
  358.     vw->vw_Flags &= ~VWFF_MESSAGE;
  359. }
  360.  
  361. void
  362. refresh_message(VW *vw)
  363. {
  364.     if(vw->vw_Message)
  365.     {
  366.     int len = vw->vw_MessageLen;
  367.     if(len >= vw->vw_MaxX)
  368.         redraw_message(vw, vw->vw_Message + (len - vw->vw_MaxX) + 1,
  369.              vw->vw_MaxX - 1);
  370.     else
  371.         redraw_message(vw, vw->vw_Message, len);
  372.     }
  373.     else
  374.     redraw_message(vw, "", 0);
  375. }
  376.  
  377. _PR VALUE cmd_message(VALUE string, VALUE now);
  378. DEFUN("message", cmd_message, subr_message, (VALUE string, VALUE now), V_Subr2, DOC_message) /*
  379. ::doc:message::
  380. message STRING [DISPLAY-NOW]
  381.  
  382. Temporarily sets the status display to STRING, this won't happen until the
  383. window is next refreshed unless DISPLAY-NOW is non-nil.
  384. ::end:: */
  385. {
  386.     DECLARE1(string, STRINGP);
  387.     message(VSTR(string));
  388.     if(!NILP(now))
  389.     {
  390.     refresh_message(curr_vw);
  391.     curr_vw->vw_Flags &= ~VWFF_REFRESH_STATUS;
  392. #ifdef HAVE_X11
  393.     XFlush(x11_display);
  394. #endif
  395.     }
  396.     return(string);
  397. }
  398.  
  399. _PR VALUE cmd_font_name(VALUE vw);
  400. DEFUN("font-name", cmd_font_name, subr_font_name, (VALUE vw), V_Subr1, DOC_font_name) /*
  401. ::doc:font_name::
  402. font-name [WINDOW]
  403.  
  404. Returns the name of the font being used in this window.
  405. ::end:: */
  406. {
  407.     if(!WINDOWP(vw))
  408.     vw = VAL(curr_vw);
  409.     return(VWIN(vw)->vw_FontName);
  410. }
  411.  
  412. _PR VALUE var_max_scroll(VALUE val);
  413. DEFUN("max-scroll", var_max_scroll, subr_max_scroll, (VALUE val), V_Var, DOC_max_scroll) /*
  414. ::doc:max_scroll::
  415. Maximum scroll distance (number of lines). If a set of lines has to be
  416. scrolled further than this the whole window is redrawn.
  417. ::end:: */
  418. {
  419.     VW *vw = curr_vw;
  420.     if(val)
  421.     {
  422.     if(NUMBERP(val))
  423.         vw->vw_MaxScroll = VNUM(val);
  424.     return(NULL);
  425.     }
  426.     return(make_number(vw->vw_MaxScroll));
  427. }
  428.  
  429. _PR VALUE var_y_scroll_step_ratio(VALUE val);
  430. DEFUN("y-scroll-step-ratio", var_y_scroll_step_ratio, subr_y_scroll_step_ratio, (VALUE val), V_Var, DOC_y_scroll_step_ratio) /*
  431. ::doc:y_scroll_step_ratio::
  432. Controls the actual number of lines scrolled when the cursor moves out of
  433. view. The number of lines to move the display origin is calcualted with the
  434. formula:
  435.   LINES_TO_SCROLL = TOTAL_LINES_IN_WINDOW / y-scroll-step-ratio
  436. If the value is 0 then the window will be scrolled by one line.
  437. ::end:: */
  438. {
  439.     VW *vw = curr_vw;
  440.     if(val)
  441.     {
  442.     if(NUMBERP(val))
  443.     {
  444.         vw->vw_YStepRatio = VNUM(val);
  445.         sys_update_dimensions(vw);
  446.     }
  447.     return(NULL);
  448.     }
  449.     return(make_number(vw->vw_YStepRatio));
  450. }
  451.  
  452. _PR VALUE var_x_scroll_step_ratio(VALUE val);
  453. DEFUN("x-scroll-step-ratio", var_x_scroll_step_ratio, subr_x_scroll_step_ratio, (VALUE val), V_Var, DOC_x_scroll_step_ratio) /*
  454. ::doc:x_scroll_step_ratio::
  455. Controls the actual number of columns scrolled when the cursor moves out of
  456. view. The number of lines to move the display origin is calcualted with the
  457. formula:
  458.   COLUMNS_TO_SCROLL = TOTAL_COLUMNS_IN_WINDOW / x-scroll-step-ratio
  459. If the value is 0 then the window will be scrolled by one column.
  460. ::end:: */
  461. {
  462.     VW *vw = curr_vw;
  463.     if(val)
  464.     {
  465.     if(NUMBERP(val))
  466.     {
  467.         vw->vw_XStepRatio = VNUM(val);
  468.         sys_update_dimensions(vw);
  469.     }
  470.     return(NULL);
  471.     }
  472.     return(make_number(vw->vw_XStepRatio));
  473. }
  474.  
  475. _PR VALUE cmd_rect_blocks_p(VALUE vw);
  476. DEFUN("rect-blocks-p", cmd_rect_blocks_p, subr_rect_blocks_p, (VALUE vw), V_Subr1, DOC_rect_blocks_p) /*
  477. ::doc:rect_blocks_p::
  478. rect-blocks-p [WINDOW]
  479.  
  480. Returns t if blocks marked in WINDOW (or the current one) are treated as
  481. rectangles.
  482. ::end:: */
  483. {
  484.     if(!WINDOWP(vw))
  485.     vw = VAL(curr_vw);
  486.     if(VWIN(vw)->vw_Flags & VWFF_RECTBLOCKS)
  487.     return(sym_t);
  488.     return(sym_nil);
  489. }
  490.  
  491. _PR VALUE cmd_set_rect_blocks(VALUE vw, VALUE stat);
  492. DEFUN("set-rect-blocks", cmd_set_rect_blocks, subr_set_rect_blocks, (VALUE vw, VALUE stat), V_Subr2, DOC_set_rect_blocks) /*
  493. ::doc:set_rect_blocks::
  494. set-rect-blocks WINDOW STATUS
  495.  
  496. Controls whether or not blocks are taken as contiguous regions of text or as
  497. rectangles in WINDOW. When STATUS is t rectangles are used.
  498. ::end:: */
  499. {
  500.     int oflags;
  501.     if(!WINDOWP(vw))
  502.     vw = VAL(curr_vw);
  503.     oflags = VWIN(vw)->vw_Flags;
  504.     if(NILP(stat))
  505.     VWIN(vw)->vw_Flags &= ~VWFF_RECTBLOCKS;
  506.     else
  507.     VWIN(vw)->vw_Flags |= VWFF_RECTBLOCKS;
  508.     if((VWIN(vw)->vw_BlockStatus == 0) && (VWIN(vw)->vw_Flags != oflags))
  509.     set_block_refresh(VWIN(vw));
  510.     return(stat);
  511. }
  512.  
  513. _PR VALUE cmd_window_asleep_p(void);
  514. DEFUN("window-asleep-p", cmd_window_asleep_p, subr_window_asleep_p, (void), V_Subr0, DOC_window_asleep_p) /*
  515. ::doc:window_asleep_p::
  516. window-asleep-p
  517.  
  518. Returns t if window is currently iconified.
  519. ::end:: */
  520. {
  521.     if(curr_vw->vw_Flags & VWFF_SLEEPING)
  522.     return(sym_t);
  523.     return(sym_nil);
  524. }
  525.  
  526. _PR VALUE cmd_window_count(void);
  527. DEFUN("window-count", cmd_window_count, subr_window_count, (void), V_Subr0, DOC_window_count) /*
  528. ::doc:window_count::
  529. window-count
  530.  
  531. Number of opened windows.
  532. ::end:: */
  533. {
  534.     return(make_number(window_count));
  535. }
  536.  
  537. _PR VALUE cmd_position_window(VALUE left, VALUE top, VALUE width, VALUE height);
  538. DEFUN("position-window", cmd_position_window, subr_position_window, (VALUE left, VALUE top, VALUE width, VALUE height), V_Subr4, DOC_position_window) /*
  539. ::doc:position_window::
  540. position-window LEFT TOP WIDTH HEIGHT
  541.  
  542. Sets the position and dimensions of the current window. These are all
  543. *pixel* measurememnts.
  544. ::end:: */
  545. {
  546.     VW *vw = curr_vw;
  547.     DECLARE1(left, NUMBERP);
  548.     DECLARE2(top, NUMBERP);
  549.     DECLARE3(width, NUMBERP);
  550.     DECLARE4(height, NUMBERP);
  551.     sys_set_vw_pos(vw, VNUM(left), VNUM(top), VNUM(width), VNUM(height));
  552.     return(sym_t);
  553. }
  554.  
  555. _PR VALUE cmd_current_window(void);
  556. DEFUN("current-window", cmd_current_window, subr_current_window, (void), V_Subr0,  DOC_current_window) /*
  557. ::doc:current_window::
  558. current-window
  559.  
  560. Returns the currently active window. Note that this is the editor's notion
  561. of `current' -- it doesn't necessarily mean that this is the window to which
  562. your window system will send input events to.
  563. ::end:: */
  564. {
  565.     return(VAL(curr_vw));
  566. }
  567.  
  568. _PR VALUE cmd_with_window(VALUE args);
  569. DEFUN("with-window", cmd_with_window, subr_with_window, (VALUE args), V_SF, DOC_with_window) /*
  570. ::doc:with_window::
  571. with-window WINDOW FORMS...
  572.  
  573. Set the editor's current window to WINDOW and evaluate FORMS, then
  574. reinstall the original window as the current one.
  575. ::end:: */
  576. {
  577.     if(CONSP(args))
  578.     {
  579.     GCVAL gcv_args;
  580.     VALUE res;
  581.     PUSHGC(gcv_args, args);
  582.     if((res = cmd_eval(VCAR(args))) && WINDOWP(res))
  583.     {
  584.         VALUE oldvw = VAL(curr_vw);
  585.         GCVAL gcv_oldvw;
  586.         curr_vw = VWIN(res);
  587.         PUSHGC(gcv_oldvw, oldvw);
  588.         res = cmd_progn(VCDR(args));
  589.         POPGC;
  590.         curr_vw = VWIN(oldvw);
  591.     }
  592.     POPGC;
  593.     return(res);
  594.     }
  595.     return(NULL);
  596. }
  597.  
  598. _PR VALUE cmd_set_current_window(VALUE vw, VALUE activ);
  599. DEFUN("set-current-window", cmd_set_current_window, subr_set_current_window, (VALUE vw, VALUE activ), V_Subr2,  DOC_set_current_window) /*
  600. ::doc:set_current_window::
  601. set-current-window WINDOW [ACTIVATE-P]
  602.  
  603. Sets the window which jade reguards as current.
  604. If ACTIVATE-P is non-nil the window will be activated with respect to the
  605. window-system (under X11 this means warping the pointer to the top left corner
  606. of the window as well).
  607. ::end:: */
  608. {
  609.     DECLARE1(vw, WINDOWP);
  610.     curr_vw = VWIN(vw);
  611.     if(!NILP(activ))
  612.     sys_activate_win(VWIN(vw));
  613.     return(VAL(curr_vw));
  614. }
  615.  
  616. _PR VALUE cmd_window_id(VALUE vw);
  617. DEFUN("window-id", cmd_window_id, subr_window_id, (VALUE vw), V_Subr1, DOC_window_id) /*
  618. ::doc:window_id::
  619. window-id [WINDOW]
  620.  
  621. Returns the identifier of the physical window that the Lisp window WINDOW
  622. points to. This is window-system dependant, under X11 it will be some integer,
  623. under Intuition a pointer (integer) to the window structure.
  624. ::end:: */
  625. {
  626.     if(!WINDOWP(vw))
  627.     vw = VAL(curr_vw);
  628.     return(make_number((long)VWIN(vw)->vw_Window));
  629. }
  630.  
  631. _PR VALUE cmd_font_x_size(VALUE vw);
  632. DEFUN("font-x-size", cmd_font_x_size, subr_font_x_size, (VALUE vw), V_Subr1, DOC_font_x_size) /*
  633. ::doc:font_x_size::
  634. font-x-size [WINDOW]
  635.  
  636. Returns the width of the window's font (in pixels).
  637. ::end:: */
  638. {
  639.     if(!WINDOWP(vw))
  640.     vw = VAL(curr_vw);
  641.     return(make_number((long)VWIN(vw)->vw_FontX));
  642. }
  643.  
  644. _PR VALUE cmd_font_y_size(VALUE vw);
  645. DEFUN("font-y-size", cmd_font_y_size, subr_font_y_size, (VALUE vw), V_Subr1, DOC_font_x_size) /*
  646. ::doc:font_y_size::
  647. font-y-size [WINDOW]
  648.  
  649. Returns the height of the window's font (in pixels).
  650. ::end:: */
  651. {
  652.     if(!WINDOWP(vw))
  653.     vw = VAL(curr_vw);
  654.     return(make_number((long)VWIN(vw)->vw_FontY));
  655. }
  656.  
  657. _PR VALUE var_status_line_cursor(VALUE val);
  658. DEFUN("status-line-cursor", var_status_line_cursor, subr_status_line_cursor, (VALUE val), V_Var, DOC_status_line_cursor) /*
  659. ::doc:status_line_cursor::
  660. When this window-local variable is non-nil the window's cursor is drawn at
  661. the end of the message in the status line, not in the main display.
  662. ::end:: */
  663. {
  664.     if(val)
  665.     {
  666.     if(NILP(val))
  667.         curr_vw->vw_Flags &= ~VWFF_STATUS_CURS;
  668.     else
  669.         curr_vw->vw_Flags |= VWFF_STATUS_CURS;
  670.     return(val);
  671.     }
  672.     return(curr_vw->vw_Flags & VWFF_STATUS_CURS ? sym_t : sym_nil);
  673. }
  674.  
  675. _PR VALUE var_buffer_list(VALUE val);
  676. DEFUN("buffer-list", var_buffer_list, subr_buffer_list, (VALUE val), V_Var, DOC_buffer_list) /*
  677. ::doc:buffer_list::
  678. List of buffers in most-recently-used order. Each window has it's own.
  679. ::end:: */
  680. {
  681.     if(val)
  682.     curr_vw->vw_BufferList = val;
  683.     return(curr_vw->vw_BufferList);
  684. }
  685.  
  686. void
  687. windows_init(void)
  688. {
  689.     ADD_SUBR(subr_make_window);
  690.     ADD_SUBR(subr_destroy_window);
  691.     ADD_SUBR(subr_sleep_window);
  692.     ADD_SUBR(subr_unsleep_window);
  693.     ADD_SUBR(subr_next_window);
  694.     ADD_SUBR(subr_message);
  695.     ADD_SUBR(subr_font_name);
  696.     ADD_SUBR(subr_max_scroll);
  697.     ADD_SUBR(subr_y_scroll_step_ratio);
  698.     ADD_SUBR(subr_x_scroll_step_ratio);
  699.     ADD_SUBR(subr_rect_blocks_p);
  700.     ADD_SUBR(subr_set_rect_blocks);
  701.     ADD_SUBR(subr_window_asleep_p);
  702.     ADD_SUBR(subr_window_count);
  703.     ADD_SUBR(subr_position_window);
  704.     ADD_SUBR(subr_current_window);
  705.     ADD_SUBR(subr_set_current_window);
  706.     ADD_SUBR(subr_with_window);
  707.     ADD_SUBR(subr_window_id);
  708.     ADD_SUBR(subr_font_x_size);
  709.     ADD_SUBR(subr_font_y_size);
  710.     ADD_SUBR(subr_status_line_cursor);
  711.     ADD_SUBR(subr_buffer_list);
  712.     INTERN(sym_make_window_hook, "make-window-hook");
  713.     INTERN(sym_destroy_window_hook, "destroy-window-hook");
  714. }
  715.  
  716. void
  717. windows_kill(void)
  718. {
  719.     VW *vw, *nxt;
  720.     while(curr_vw)
  721.     cmd_destroy_window(VAL(curr_vw));
  722.     vw = view_chain;
  723.     while(vw)
  724.     {
  725.     nxt = vw->vw_Next;
  726.     myfree(vw);
  727.     vw = nxt;
  728.     }
  729.     view_chain = NULL;
  730. }
  731.  
  732. void
  733. window_sweep(void)
  734. {
  735.     VW *vw = view_chain;
  736.     view_chain = NULL;
  737.     while(vw)
  738.     {
  739.     VW *nxt = vw->vw_Next;
  740.     if(GC_MARKEDP(VAL(vw)))
  741.     {
  742.         GC_CLR(VAL(vw));
  743.         vw->vw_Next = view_chain;
  744.         view_chain = vw;
  745.     }
  746.     else
  747.         myfree(vw);
  748.     vw = nxt;
  749.     }
  750. }
  751.  
  752. void
  753. window_prin(VALUE strm, VALUE vw)
  754. {
  755.     u_char buf[40];
  756.     if(VWIN(vw)->vw_Window)
  757.     {
  758. #ifdef HAVE_X11
  759.     sprintf(buf, "#<window %ld ", VWIN(vw)->vw_Window);
  760. #else
  761.     sprintf(buf, "#<window 0x%x ", VWIN(vw)->vw_Window);
  762. #endif
  763.     stream_puts(strm, buf, -1, FALSE);
  764.     stream_puts(strm, VSTR(VWIN(vw)->vw_Tx->tx_BufferName), -1, TRUE);
  765.     stream_putc(strm, '>');
  766.     }
  767.     else
  768.     stream_puts(strm, "#<dead-window>", -1, FALSE);
  769. }
  770.